package subraSoft.fenix.model.cliente.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import subraSoft.centaurus.model.cobj.CenDefaultCObj;
import subraSoft.centaurus.model.domain.CenDefaultDO;
import subraSoft.centaurus.model.service.CenIABMService;
import subraSoft.centaurus.model.service.CenIPaginableService;
import subraSoft.centaurus.model.service.impl.CenDefaultServiceImpl;
import subraSoft.fenix.model.cliente.cobj.FenClienteCObj;
import subraSoft.fenix.model.cliente.cobj.FenClienteQueryCObj;
import subraSoft.fenix.model.cliente.domain.FenClienteDO;
import subraSoft.fenix.model.cliente.service.FenClienteService;
import subraSoft.fenix.model.reparacion.domain.FenReparacionDO;

public class FenClienteServiceImpl extends CenDefaultServiceImpl 
implements FenClienteService, CenIABMService, CenIPaginableService
{
	@SuppressWarnings("unchecked")
	public List<CenDefaultCObj> getList() 
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		List<CenDefaultCObj> res = new ArrayList<CenDefaultCObj>();
		Criteria c = session.createCriteria(FenClienteDO.class);
		
		List<FenClienteDO> clientes = c.list();
		
		for (FenClienteDO fenClienteDO : clientes) 
		{
			res.add(getCObj(fenClienteDO));
		}
		
		session.getTransaction().commit();
		return res;
	}
	
	private FenClienteCObj getCObj(FenClienteDO clienteDO)
	{
		FenClienteCObj clienteCObj = new FenClienteCObj();
		clienteCObj.setCelular(clienteDO.getCelular());
		clienteCObj.setCodigoPostal(clienteDO.getCodigoPostal());
		clienteCObj.setContacto(clienteDO.getContacto());
		clienteCObj.setDni(clienteDO.getDni());
		clienteCObj.setCuit(clienteDO.getCuit());
		clienteCObj.setDireccion(clienteDO.getDireccion());
		clienteCObj.setEmail(clienteDO.getEmail());
		clienteCObj.setId(clienteDO.getId());
		clienteCObj.setLocalidad(clienteDO.getLocalidad());
		clienteCObj.setNombre(clienteDO.getNombre());
		clienteCObj.setObservaciones(clienteDO.getObservaciones());
		clienteCObj.setProvincia(clienteDO.getProvincia());
		clienteCObj.setTelefono(clienteDO.getTelefono());
		clienteCObj.setTipoIVA(clienteDO.getTipoIVA());

		return clienteCObj;
	}
	
	public Long saveOrUpdate(CenDefaultCObj cObj) 
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();

		FenClienteCObj cliCObj = (FenClienteCObj)cObj;
		FenClienteDO cli = null;
		
		if( cliCObj.getId() == null )
		{
			cli = new FenClienteDO();
		}
		else
		{
			cli = (FenClienteDO) session.get(FenClienteDO.class, cliCObj.getId());
		}
		
		cli.setCelular(cliCObj.getCelular());
		cli.setCodigoPostal(cliCObj.getCodigoPostal());
		cli.setContacto(cliCObj.getContacto());
		cli.setCuit(cliCObj.getCuit());
		cli.setDireccion(cliCObj.getDireccion());
		cli.setDni(cliCObj.getDni());
		cli.setEmail(cliCObj.getEmail());
		cli.setLocalidad(cliCObj.getLocalidad());
		cli.setNombre(cliCObj.getNombre());
		cli.setObservaciones(cliCObj.getObservaciones());
		cli.setProvincia(cliCObj.getProvincia());
		cli.setTelefono(cliCObj.getTelefono());
		cli.setTipoIVA(cliCObj.getTipoIVA());
		
		session.saveOrUpdate(cli);
		
		session.getTransaction().commit();
		
		return cli.getId();
	}

	public void delete(CenDefaultCObj clienteCObj) 
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		FenClienteDO clienteDO = (FenClienteDO)session.load(FenClienteDO.class, (Long)clienteCObj.getId()); //  TODO load or get
		
		session.delete(clienteDO);
		
		session.getTransaction().commit();
	}
	
	@Deprecated
	public Long getClienteIdPorCuitDni(String dni, String cuit)
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		Criteria crit = session.createCriteria(FenClienteDO.class);
		if(dni != null && !dni.equals(""))
			crit.add(Restrictions.eq("dni", dni));
		if(cuit != null && !cuit.equals(""))
			crit.add(Restrictions.eq("cuit", cuit));
		
		FenClienteDO cliente = (FenClienteDO)crit.uniqueResult();
		
		session.getTransaction().commit();
		
		if(cliente != null)
			return cliente.getId();
		else
			return null;
	}
	
	@SuppressWarnings("unchecked")
	public List<CenDefaultCObj> getClientesBy(FenClienteQueryCObj cliQ)
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		List<CenDefaultCObj> res = new ArrayList<CenDefaultCObj>();
		Criteria c = session.createCriteria(FenClienteDO.class);
		if(cliQ.getId() != null)
			c.add( Restrictions.eq("id", cliQ.getId()) );
		
		if(cliQ.getNombre() != null && !cliQ.getNombre().isEmpty())
			c.add( Restrictions.like("nombre", "%"+cliQ.getNombre()+"%"));
		if(cliQ.getDireccion() != null && !cliQ.getDireccion().isEmpty())
			c.add( Restrictions.like("direccion", "%"+cliQ.getDireccion()+"%"));		
		
		if(cliQ.getLocalidad() != null && !cliQ.getLocalidad().isEmpty())
			c.add( Restrictions.like("localidad", "%"+cliQ.getLocalidad()+"%"));
		if(cliQ.getCodigoPostal() != null && !cliQ.getCodigoPostal().isEmpty())
			c.add( Restrictions.eq("codigoPostal", cliQ.getCodigoPostal()));	
		
		if(cliQ.getTelefono() != null && !cliQ.getTelefono().isEmpty())
			c.add( Restrictions.eq("telefono", cliQ.getTelefono()));
		if(cliQ.getCelular() != null && !cliQ.getCelular().isEmpty())
			c.add( Restrictions.eq("celular", cliQ.getCelular()));	
		
		if(cliQ.getDni() != null && !cliQ.getDni().isEmpty())
			c.add( Restrictions.eq("dni", cliQ.getDni()) );
		
		if(cliQ.getCuit() != null && !cliQ.getCuit().isEmpty())
			c.add( Restrictions.eq("cuit", cliQ.getCuit()) );
		
		if(cliQ.getContacto() != null && !cliQ.getContacto().isEmpty())
			c.add( Restrictions.like("contacto", "%"+cliQ.getContacto()+"%") );
		
		if(cliQ.getEmail() != null && !cliQ.getEmail().isEmpty())
			c.add( Restrictions.eq("email", cliQ.getEmail()) );
		
		if(cliQ.getProvincia() != null && !cliQ.getProvincia().isEmpty())
			c.add( Restrictions.like("provincia", cliQ.getProvincia()) );
		
		if(cliQ.getTipoIva() != null)
			c.add( Restrictions.eq("tipoIVA", cliQ.getTipoIva()) );
		
		List<CenDefaultDO> clientes = (List<CenDefaultDO>)c.list();
		
		for (CenDefaultDO fenClienteDO : clientes) 
		{
			res.add(getCObj((FenClienteDO) fenClienteDO));
		}
		
		session.getTransaction().commit();
		return res;
	}
	
	public FenClienteCObj getClienteById(Long id)
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		FenClienteDO cliente = (FenClienteDO) session.get(FenClienteDO.class, id);
		
		session.getTransaction().commit();
		return getCObj(cliente);
	}

	public boolean clientePoseeRepaciones(Long id)
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		FenClienteDO cliente = (FenClienteDO) session.get(FenClienteDO.class, id);
		List<FenReparacionDO> reps = cliente.getReparaciones();
		boolean poseeReparaciones = ((reps != null) && reps.size() != 0 );
		
		session.getTransaction().commit();
		return poseeReparaciones;
	}

	@SuppressWarnings("unchecked")
	public List<CenDefaultCObj> getList(int startIndex, int pageSize)
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		List<CenDefaultCObj> res = new ArrayList<CenDefaultCObj>();
		Criteria c = session.createCriteria(FenClienteDO.class);
		
		c.setFirstResult(startIndex);
		c.setMaxResults(pageSize);
		
		List<FenClienteDO> clientes = c.list();
		
		for (FenClienteDO fenClienteDO : clientes) 
		{
			res.add(getCObj(fenClienteDO));
		}
		
		session.getTransaction().commit();
		return res;
	}

	public int getSize() 
	{
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		int res = (Integer)session.createCriteria(FenClienteDO.class).setProjection(Projections.rowCount()).uniqueResult();
		session.getTransaction().commit();
		return res;
	}
}
